package com.ifonly.initialize;


import com.google.common.base.Strings;
import com.ifonly.activerecord.Model;
import com.ifonly.common.ClassScanner;
import com.ifonly.config.Configuration;
import com.ifonly.config.Constants;
import com.ifonly.core.ClassContainer;
import com.ifonly.logger.Logger;
import com.ifonly.mvc.Controller;
import com.ifonly.mvc.IfOnlyFilter;
import com.ifonly.security.AbstractAppShiroRealm;
import com.ifonly.security.IfOnlyShiroFilter;
import org.apache.shiro.web.env.EnvironmentLoaderListener;
import org.apache.shiro.web.servlet.ShiroFilter;

import javax.servlet.*;
import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

/**
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-09 14:16
 * @since JDK 1.6
 */
public class IfOnlyContextInitializer implements ServletContainerInitializer {
    /**
     * 获取 Configuration 实例并进行初始化
     */
    private Configuration cfg = Configuration.getInstance().init();

    /**
     * 需要扫描的类
     */
    private static final Class<?>[] CLASSES = new Class[]{
            Controller.class,
            Model.class,
            AbstractAppShiroRealm.class
    };

    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        System.out.println("-------------------- ifonly startup --------------------");

        ClassContainer instance = ClassContainer.getInstance(CLASSES);
        try {

            List<Class<?>> list = ClassScanner.of("app")
                    .from(instance.groupTypesArray())
                    .scan();

            instance.fillGroup(list);
        } catch (IOException e) {
            throw new RuntimeException("class scan failed", e);
        }


        EnumSet<DispatcherType> dispatcherTypes = EnumSet.allOf(DispatcherType.class);

        Logger.setLoggerFactory(cfg.getLoggerFactory());

        if (cfg.isSecurity()) {
            initShiro(ctx, dispatcherTypes);
        }

        FilterRegistration.Dynamic ifOnlyFilter = ctx.addFilter("IfOnlyFilter@ifonly", IfOnlyFilter.class);
        ifOnlyFilter.setInitParameter(Constants.CONFIG_CLASS, "com.ifonly.initialize.IfOnlyAutoConfig");
        ifOnlyFilter.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
    }

    private void initShiro(ServletContext ctx, EnumSet<DispatcherType> dispatcherTypes) {
        if (!Strings.isNullOrEmpty(cfg.getSecurityFile())) { //采用配置文件
            ctx.addListener(EnvironmentLoaderListener.class);
            FilterRegistration.Dynamic shiroFilter = ctx.addFilter("IfOnly@ShiroFilter", ShiroFilter.class);
            shiroFilter.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
            shiroFilter.setInitParameter("shiroConfigLocations", cfg.getSecurityFile());
        } else {
            FilterRegistration.Dynamic shiroFilter = ctx.addFilter("IfOnly@ShiroFilter", IfOnlyShiroFilter.class);
            shiroFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
        }
    }

}
